var pubsub = (function(){
    /*
        topics={'msg':[{token:1,func:function(topic,args){}}]}
    */
    var q = {}
        topics = {},
        subUid = -1;
    //发布消息
    q.publish = function(topic, args) {
        //判断有没有当前的话题
        if(!topics[topic]) {return;}
        var subs = topics[topic],//当前话题订阅者数组
            len = subs.length;
        while(len--) {
            subs[len].func(topic, args);
        }
        return this;
    };
    //订阅事件
    //接收两个参数 要订阅的话题，处理程序
    q.subscribe = function(topic, func) {
        //如果当前话题已经有订阅者，获取到订阅者数组
        //一个话题名下的 订阅者事件可以是多个fn1, fn2, fn3
        topics[topic] = topics[topic] ? topics[topic] : [];
        
        //给每个订阅者添加唯一的token
        var token = (++subUid).toString();
        topics[topic].push({
            token : token,
            func : func
        });
        return token;
    };
    //取消订阅
    q.unsubscribe = function(token){
        Object.keys(topics).map( key => {
            topics[key].map((fn, fnIndex) => {
                if(fn.token == token){
                    topics[key].splice(fnIndex,1)
                }
            })
        })
    }
    return q;
})();
